/*
   Copyright 2009 Bégaudeau Stéphane

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
 */

package faneclipse.ast;

import java.util.List;
import java.util.Map;

/**
 * @author BEGAUDEAU stephane
 */
public abstract class FanAbstractSyntaxTreeNode {
	/**
	 * Node type constant indicating a node of type anonymous class declaration.
	 */
	public static final int ANONYMOUS_CLASS_DECLARATION = 1;
	
	/**
	 * Node type constant indicating a node of type array access.
	 */
	public static final int ARRAY_ACCESS = 2;
	
	/**
	 * Node type constant indicating a node of type array creation.
	 */
	public static final int ARRAY_CREATION = 3;
	
	/**
	 * Node type constant indicating a node of type array initializer.
	 */
	public static final int ARRAY_INITIALIZER = 4;
	
	/**
	 * Node type constant indicating a node of type array type.
	 */
	public static final int ARRAY_TYPE = 5;
	
	/**
	 * Node type constant indicating a node of type assert statement.
	 */
	public static final int ASSERT_STATEMENT = 6;
	
	/**
	 * Node type constant indicating a node of type assignment.
	 */
	public static final int ASSIGNMENT = 7;
	
	/**
	 * Node type constant indicating a node of type block.
	 */
	public static final int BLOCK = 8;
	
	/**
	 * Node type constant indicating a node of type boolean literal.
	 */
	public static final int BOOLEAN_LITERAL = 9;
	
	/**
	 * Node type constant indicating a node of type break statement.
	 */
	public static final int BREAK_STATEMENT = 10;
	
	/**
	 * Node type constant indicating a node of type cast expression.
	 */
	public static final int CAST_EXPRESSION = 11;
	
	/**
	 * Node type constant indicating a node of type catch clause.
	 */
	public static final int CATCH_CLAUSE = 12;
	
	/**
	 * Node type constant indicating a node of type character literal.
	 */
	public static final int CHARACTER_LITERAL = 13;
	
	/**
	 * Node type constant indicating a node of type class instance creation.
	 */
	public static final int CLASS_INSTANCE_CREATION = 14;
	
	/**
	 * Node type constant indicating a node of type compilation unit.
	 */
	public static final int COMPILATION_UNIT = 15;
	
	/**
	 * Node type constant indicating a node of type conditional expression.
	 */
	public static final int CONDITIONAL_EXPRESSION = 16;
	
	/**
	 * Node type constant indicating a node of type constructor invocation.
	 */
	public static final int CONSTRUCTOR_INVOCATION = 17;
	
	/**
	 * Node type constant indicating a node of type continue statement.
	 */
	public static final int CONTINUE_STATEMENT = 18;
	
	/**
	 * Node type constant indicating a node of type do statement.
	 */
	public static final int DO_STATEMENT = 19;
	
	/**
	 * Node type constant indicating a node of type empty statement.
	 */
	public static final int EMPTY_STATEMENT = 20;
	
	/**
	 * Node type constant indicating a node of type expression statement.
	 */
	public static final int EXPRESSION_STATEMENT = 21;
	
	/**
	 * Node type constant indicating a node of type fandoc.
	 */
	public static final int FANDOC = 22;
	
	/**
	 * Node type constant indicating a node of type field access.
	 */
	public static final int FIELD_ACCESS = 23;
	
	/**
	 * Node type constant indicating a node of type field declaration.
	 */
	public static final int FIELD_DECLARATION = 24;
	
	/**
	 * Node type constant indicating a node of type for statement.
	 */
	public static final int FOR_STATEMENT = 25;
	
	/**
	 * Node type constant indicating a node of type if statement.
	 */
	public static final int IF_STATEMENT = 26;
	
	/**
	 * Node type constant indicating a node of type import declaration.
	 */
	public static final int IMPORT_DECLARATION = 27;
	
	/**
	 * Node type constant indicating a node of type infix declaration.
	 */
	public static final int INFIX_EXPRESSION = 28;
	
	/**
	 * Node type constant indicating a node of type initializer.
	 */
	public static final int INITIALIZER = 29;
	
	/**
	 * Node type constant indicating a node of type labeled statement.
	 */
	public static final int LABELED_STATEMENT = 30;
	
	/**
	 * Node type constant indicating a node of type method declaration.
	 */
	public static final int METHOD_DECLARATION = 31;
	
	/**
	 * Node type constant indicating a node of type method invocation.
	 */
	public static final int METHOD_INVOCATION = 32;
	
	/**
	 * Node type constant indicating a node of type null literal.
	 */
	public static final int NULL_LITERAL = 33;
	
	/**
	 * Node type constant indicating a node of type number literal.
	 */
	public static final int NUMBER_LITERAL = 34;
	
	/**
	 * Node type constant indicating a node of type package declaration.
	 */
	public static final int PACKAGE_DECLARATION = 35;
	
	/**
	 * Node type constant indicating a node of type parenthesized expression.
	 */
	public static final int PARENTHESIZED_EXPRESSION = 36;
	
	/**
	 * Node type constant indicating a node of type postfix expression.
	 */
	public static final int POSTFIX_EXPRESSION = 37;
	
	/**
	 * Node type constant indicating a node of type prefix expression.
	 */
	public static final int PREFIX_EXPRESSION = 38;
	
	/**
	 * Node type constant indicating a node of type primitive type.
	 */
	public static final int PRIMITIVE_TYPE = 39;
	
	/**
	 * Node type constant indicating a node of type qualified name.
	 */
	public static final int QUALIFIED_NAME = 40;
	
	/**
	 * Node type constant indicating a node of type return statement.
	 */
	public static final int RETURN_STATEMENT = 41;
	
	/**
	 * Node type constant indicating a node of type simple name.
	 */
	public static final int SIMPLE_NAME = 42;
	
	/**
	 * Node type constant indicating a node of type simple type.
	 */
	public static final int SIMPLE_TYPE = 43;
	
	/**
	 * Node type constant indicating a node of type single variable declaration.
	 */
	public static final int SINGLE_VARIABLE_DECLARATION = 44;
	
	/**
	 * Node type constant indicating a node of type string literal.
	 */
	public static final int STRING_LITERAL = 45;
	
	/**
	 * Node type constant indicating a node of type super constructor invocation.
	 */
	public static final int SUPER_CONSTRUCTOR_INVOCATION = 46;
	
	/**
	 * Node type constant indicating a node of type super field access.
	 */
	public static final int SUPER_FIELD_ACCESS = 47;
	
	/**
	 * Node type constant indicating a node of type super method invocation.
	 */
	public static final int SUPER_METHOD_INVOCATION = 48;
	
	/**
	 * Node type constant indicating a node of type switch case.
	 */
	public static final int SWITCH_CASE = 49;
	
	/**
	 * Node type constant indicating a node of type switch statement.
	 */
	public static final int SWITCH_STATEMENT = 50;
	
	/**
	 * Node type constant indicating a node of type synchronized statement.
	 */
	public static final int SYNCHRONIZED_STATEMENT = 51;
	
	/**
	 * Node type constant indicating a node of type this expression.
	 */
	public static final int THIS_EXPRESSION = 52;
	
	/**
	 * Node type constant indicating a node of type throw statement.
	 */
	public static final int THROW_STATEMENT = 53;
	
	/**
	 * Node type constant indicating a node of type try statement.
	 */
	public static final int TRY_STATEMENT = 54;
	
	/**
	 * Node type constant indicating a node of type type declaration.
	 */
	public static final int TYPE_DECLARATION = 55;
	
	/**
	 * Node type constant indicating a node of type type declaration statement.
	 */
	public static final int TYPE_DECLARATION_STATEMENT = 56;
	
	/**
	 * Node type constant indicating a node of type type literal.
	 */
	public static final int TYPE_LITERAL = 57;
	
	/**
	 * Node type constant indicating a node of type variable declaration expression.
	 */
	public static final int VARIABLE_DECLARATION_EXPRESSION = 58;
	
	/**
	 * Node type constant indicating a node of type variable declaration fragment.
	 */
	public static final int VARIABLE_DECLARATION_FRAGMENT = 59;
	
	/**
	 * Node type constant indicating a node of type variable declaration statement.
	 */
	public static final int VARIABLE_DECLARATION_STATEMENT = 60;
	
	/**
	 * Node type constant indicating a node of type while statement.
	 */
	public static final int WHILE_STATEMENT = 61;
	
	/**
	 * Node type constant indicating a node of type instanceOf expression.
	 */
	public static final int INSTANCEOF_EXPRESSION = 62;
	
	/**
	 * Node type constant indicating a node of type line comment.
	 */
	public static final int LINE_COMMENT = 63;
	
	/**
	 * Node type constant indicating a node of type block comment.
	 */
	public static final int BLOCK_COMMENT = 64;
	
	/**
	 * Node type constant indicating a node of type tag element.
	 */
	public static final int TAG_ELEMENT = 65;
	
	/**
	 * Node type constant indicating a node of type text element.
	 */
	public static final int TEXT_ELEMENT = 66;
	
	/**
	 * Node type constant indicating a node of type member reference.
	 */
	public static final int MEMBER_REF = 67;
	
	/**
	 * Node type constant indicating a node of type method reference.
	 */
	public static final int METHOD_REF = 68;
	
	/**
	 * Node type constant indicating a node of type method reference parameter.
	 */
	public static final int METHOD_REF_PARAMETER = 69;
	
	/**
	 * Node type constant indicating a node of type enhanced for statement.
	 */
	public static final int ENHANCED_FOR_STATEMENT = 70;
	
	/**
	 * Node type constant indicating a node of type enum declaration.
	 */
	public static final int ENUM_DECLARATION = 71;
	
	/**
	 * Node type constant indicating a node of type enum constant declaration.
	 */
	public static final int ENUM_CONSTANT_DECLARATION = 72;
	
	/**
	 * Node type constant indicating a node of type type parameter.
	 */
	public static final int TYPE_PARAMETER = 73;
	
	/**
	 * Node type constant indicating a node of type parameterized type.
	 */
	public static final int PARAMETERIZED_TYPE = 74;
	
	/**
	 * Node type constant indicating a node of type qualified type.
	 */
	public static final int QUALIFIED_TYPE = 75;
	
	/**
	 * Node type constant indicating a node of type wildcard type.
	 */
	public static final int WILDCARD_TYPE = 76;
	
	/**
	 * Node type constant indicating a node of type normal annotation.
	 */
	public static final int NORMAL_ANNOTATION = 77;
	
	/**
	 * Node type constant indicating a node of type marker annotation.
	 */
	public static final int MARKER_ANNOTATION = 78;
	
	/**
	 * Node type constant indicating a node of type single member annotation.
	 */
	public static final int SINGLE_MEMBER_ANNOTATION = 79;
	
	/**
	 * Node type constant indicating a node of type member value pair.
	 */
	public static final int MEMBER_VALUE_PAIR = 80;
	
	/**
	 * Node type constant indicating a node of type annotation type declaration.
	 */
	public static final int ANNOTATION_TYPE_DECLARATION = 81;
	
	/**
	 * Node type constant indicating a node of type annotation type member declaration.
	 */
	public static final int ANNOTATION_TYPE_MEMBER_DECLARATION = 82;
	
	/**
	 * Node type constant indicating a node of type modifier.
	 */
	public static final int MODIFIER = 83;
	
	/**
	 * Flag constant indicating that there is something not quite right with this node.
	 */
	public static final int MALFORMED = 84;
	
	/**
	 * Flag constant indicating that this is a node that was created by the parser (as opposed to one created by another party).
	 */
	public static final int ORIGINAL = 85;
	
	/**
	 * Flag constant indicating that this node is unmodifiable.
	 */
	public static final int PROTECT = 86;
	
	/**
	 * Flag constant indicating that this node or a part of this node is recovered from source that contains a syntax error detected in the vicinity.
	 */
	public static final int RECOVERED = 87;
	
	/**
	 * This node's FanAbstractSyntaxTree.
	 */
	private FanAbstractSyntaxTree fanAbstractSyntaxTree;
	
	/**
	 * This node's parent.
	 */
	private FanAbstractSyntaxTreeNode parent;
	
	/**
	 * List of the properties of the object.
	 */
	private Map<String, Object> properties;
	
	/**
	 * The flags of the node.
	 */
	private int flags;
	
	/**
	 * The type of the node.
	 */
	private int type;
	
	/**
	 * The constructor.
	 */
	private FanAbstractSyntaxTreeNode() {
		super();
	}
	
	/**
	 * Returns the node class for the corresponding node type.
	 * @param nodeType the type of node desired.
	 * @return The node class for the corresponding node type.
	 * @throws IllegalArgumentException If the node type is invalid.
	 */
	public static Class<?> nodeClassForType(final int nodeType) throws IllegalArgumentException {
		if(nodeType < 1 || nodeType > 87)
		{
			throw new IllegalArgumentException("Invalid node type");
		}
		else
		{
			return null;
		}
	}
	
	/**
	 * Get the FanAbstractSyntaxTree of this node.
	 * @return the FanAbstractSyntaxTree of this node.
	 */
	public final FanAbstractSyntaxTree getFanAbstractSyntaxTree() {
		return fanAbstractSyntaxTree;
	}
	
	/**
	 * Returns this node's parent node, or null if this is the root node.
	 * @return This node's parent.
	 */
	public final FanAbstractSyntaxTreeNode getParent() {
		return parent;
	}
	
	/**
	 * Returns the location of this node within its parent, or null if this is a root node.
	 * @return The location of this node in its parent, or null if this node has no parent.
	 */
	public final FanStructuralPropertyDescriptor getLocationInParent() {
		return null;
	}
	
	/**
	 * Returns this node's root.
	 * @return this node's root.
	 */
	public final FanAbstractSyntaxTreeNode getRoot() {
		return null;
	}
	
	/**
	 * Returns the value of the given structural property for this node.
	 * @param property The property.
	 * @return The value or null if none.
	 * @throws RuntimeException If the object doesn't have the given property.
	 */
	public final Object getStructuralProperty(final FanStructuralPropertyDescriptor property) throws RuntimeException {
		return null;
	}
	
	/**
	 * Sets the value of the given structural property for this node.
	 * @param property The property.
	 * @param value The object that will match this property.
	 * @throws RuntimeException If the object doesn't have the given property.
	 */
	public final void setStructuralProperty(final FanStructuralPropertyDescriptor property, final Object value) throws RuntimeException {
		
	}
	
	/**
	 * Returns a list of structural property descriptors for nodes of the same type as this node.
	 * @return A list of property descriptors.
	 */
	public final List<?> structuralPropertiesForType() {
		return null;
	}
	
	/**
	 * Delete this node from his parent.
	 */
	public final void delete() {
		
	}
	
	/**
	 * Returns the named property of this node, or null if none.
	 * @param propertyName The name of the property.
	 * @return The object corresponding to the property.
	 */
	public final Object getProperty(final String propertyName) {
		return properties.get(propertyName);
	}
	
	/**
	 * Sets the named property of this node to the given value, or to null to clear it.
	 * @param propertyName The property.
	 * @param data The object corresponding to the property.
	 */
	public final void setProperty(final String propertyName, final Object data) {
		properties.put(propertyName, data);
	}
	
	/**
	 * Returns an unmodifiable table of the properties of this node with non-null values.
	 * @return The properties.
	 */
	public final Map<String, Object> properties() {
		return properties;
	}
	
	/**
	 * Returns the flags associated with this node.
	 * @return the flags.
	 */
	public final int getFlags() {
		return flags;
	}
	
	/**
	 * Sets the flags associated with this node.
	 * @param flags The new flags.
	 */
	public final void setFlags(final int flags) {
		this.flags = flags;
	}
	
	/**
	 * Returns an integer value identifying the type of this concrete AST node.
	 * @return One of the node type constants.
	 */
	public final int getNodeType() {
		return type;
	}
	
	/**
	 * The ASTNode implementation of this Object method uses object identity.
	 * @param obj The object to compare.
	 * @return A boolean indicating if the two objects are equals.
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	public final boolean equals(final Object obj) {
		return true;
	}
	
	/**
	 * Return the hashcode value of the object.
	 * @return The hashcode.
	 * @see java.lang.Object#hashCode()
	 */
	public final int hashCode() {
		return 0;
	}
	
	/**
	 * Returns whether the subtree rooted at the given node matches the given other object as decided by the given matcher.
	 * @param matcher The matcher.
	 * @param other The other object.
	 * @return True if the subtree matches, or false if they do not match.
	 */
	public final boolean subtreeMatch(final FanAbstractSyntaxTreeMatcher matcher, final Object other) {
		return true;
	}
	
	/**
	 * Returns a deep copy of the subtree of AST nodes rooted at the given node.
	 * The resulting nodes are owned by the given AST, which may be different from the ASTs of the given node.
	 * Even if the given node has a parent, the result node will be unparented.
	 * @param target The FanAbstractSyntaxTree that is to own the nodes in the result
	 * @param node The node to copy, or null if none
	 * @return The copied node.
	 */
	public static FanAbstractSyntaxTreeNode copySubtree(final FanAbstractSyntaxTree target, final FanAbstractSyntaxTreeNode node) {
		return null;
	}
	
	/**
	 * Returns a deep copy of the subtrees of AST nodes rooted at the given list of nodes.
	 * The resulting nodes are owned by the given AST, which may be different from the ASTs of the nodes in the list.
	 * Even if the nodes in the list have parents, the nodes in the result will be unparented.
	 * @param target The FanAbstractSyntaxTree that is to own the nodes in the result.
	 * @param nodes The list of nodes to copy.
	 * @return The list of copied subtrees.
	 */
	public static List<?> copySubtrees(final FanAbstractSyntaxTree target, final List<?> nodes) {
		return null;
	}
	
	/**
	 * Accepts the given visitor on a visit of the current node.
	 * @param visitor The visitor.
	 */
	public final void accept(final FanAbstractSyntaxTreeVisitor visitor) {
		
	}
	
	/**
	 * Returns the character index into the original source file indicating where the source fragment corresponding to this node begins.
	 * @return The 0-based character index, or -1 if no source position information is recorded for this node.
	 */
	public final int getStartPosition() {
		return 0;
	}
	
	/**
	 * Returns the length in characters of the original source file indicating where the source fragment corresponding to this node ends.
	 * @return The length of the original source.
	 */
	public final int getLength() {
		return 0;
	}
	
	/**
	 * Sets the source range of the original source file where the source fragment corresponding to this node was found.
	 * @param startPosition A 0-based character index, or -1 if no source position information is available for this node
	 * @param length A (possibly 0) length, or 0 if no source position information is recorded for this node
	 */
	public final void setSourceRange(final int startPosition, final int length) {
		
	}
	
	/**
	 * Returns a string representation of this node suitable for debugging purposes only.
	 * @return String value of this object.
	 * @see java.lang.Object#toString()
	 */
	public final String toString() {
		return null;
	}
	
	/**
	 * Returns an estimate of the memory footprint in bytes of the entire subtree rooted at this node.
	 * @return The size of this subtree in bytes.
	 */
	public final int subtreeBytes() {
		return 0;
	}
	
}
